package com.example.sms.config;

import com.google.common.eventbus.Subscribe;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Service;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Method;

@Slf4j
@Configuration
@SuppressWarnings("all")
public class BusConfig implements ApplicationListener<ApplicationStartedEvent> {

    @Autowired
    private ApplicationContext context;

    @Bean
    public Bus bus() {
        return new Bus();
    }

    @Override
    public void onApplicationEvent(ApplicationStartedEvent event) {
        // 1. 找，并循环遍历所有的 @Service 类的对象。
        String[] beanNames = context.getBeanNamesForAnnotation(Service.class);
        for (String name : beanNames) {
            System.out.println(name);
            Object service = context.getBean(name);

            // 2. 找，并循环当前 @Service 类的对象的所有的方法。
            Method[] methods = ReflectionUtils.getAllDeclaredMethods(service.getClass());
            for (Method method : methods) {

                // 3. 这个 @Serivice 的所有的方法中，我们只关心有 @Subscribe 注解的那个、那些。
                System.out.println(method.getDeclaredAnnotations().length);
                if (method.getAnnotation(Subscribe.class) == null)
                    continue;

                // 4. 获得 @Subscribe 方法的参数类型
                Class<?>[] argumentTypes = method.getParameterTypes();
                if (argumentTypes.length == 0)
                    continue;

                Class<?> argumentType = argumentTypes[0];

                // 5. 注册
                log.info("未来 [{}] 类型的参数都将有 [{}] 对象的 [{}] 方法处理。", argumentType, name, method.getName());
                bus().register(argumentType, service, method);

            }
        }
    }
}
